#!/usr/bin/env php
<?php

use Nette\PhpGenerator\Literal;
use Nette\PhpGenerator\PhpFile;
use Nette\PhpGenerator\PsrPrinter;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\SingleCommandApplication;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Yaml\Yaml;
use Webmozart\Assert\Assert;

set_time_limit(0);

require __DIR__.'/../vendor/autoload.php';

(new SingleCommandApplication())
    ->setName('Generate bots class')
    ->setVersion('1.0.0')
    ->setHelp('This command will generate the Setono\BotDetectionBundle\BotDetector\Bots class')
    ->setCode(static function (InputInterface $input, OutputInterface $output) {
        $io = new SymfonyStyle($input, $output);
        $io->progressStart();

        // download
        $yaml = file_get_contents('https://raw.githubusercontent.com/matomo-org/device-detector/master/regexes/bots.yml');
        $io->progressAdvance();

        // parse
        $data = Yaml::parse($yaml);
        $io->progressAdvance();

        // generate regex
        $testRegex = static function(string $combinedRegex, string $lastRegex): void
        {
            // It doesn't matter what the subject is. All we want to test is if it compiles
            Assert::notFalse(preg_match($combinedRegex, 'Test string'), $lastRegex . ' failed');
        };

        $regexes = [];
        $regex = null;
        foreach ($data as $item) {
            $regexes[] = str_replace(' ', '\s', $item['regex']) . "\n";
            $regex = '#' . implode('|', $regexes) . '#x';
            $testRegex($regex, $item['regex']);
        }
        $io->progressAdvance();

        // generate class
        $file = new PhpFile();
        $file->addComment('This file is auto-generated by bin/generate-bots-class. Do not edit');
        $file->setStrictTypes();

        $namespace = $file->addNamespace('Setono\BotDetectionBundle\BotDetector');

        $class = $namespace->addClass('Bots');

        $class
            ->setFinal()
            ->addConstant('REGEX', new Literal(sprintf('"%s"', $regex)))->setPublic()
        ;

        $printer = new PsrPrinter();

        file_put_contents(__DIR__ . '/../src/BotDetector/Bots.php', $printer->printFile($file));
        $io->progressAdvance();

        $io->progressFinish();
    })
    ->run();
